home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / SampleSMSAMServer / StatusMonitor.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  13.0 KB  |  547 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        StatusMonitor.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #pragma segment StatusMonitor
  15.  
  16. #ifndef __STATUSMONITOR__
  17. #include "StatusMonitor.h"
  18. #endif
  19.  
  20. #ifndef __UAPPLEEVENTS__
  21. #include "UAppleEvents.h"
  22. #endif
  23.  
  24. #ifndef __STATUSDATABASE__
  25. #include "StatusDatabase.h"
  26. #endif
  27.  
  28. #ifndef __DEBUGGINGGEAR__
  29. #include "DebuggingGear.h"
  30. #endif
  31.  
  32. #ifndef __OBJECTLIST__
  33. #include "ObjectList.h"
  34. #endif
  35.  
  36. #ifndef __MAILGATEWAY__
  37. #include "MailGateway.h"
  38. #endif
  39.  
  40. #ifndef __UTILITIES__
  41. #include "Utilities.h"
  42. #endif
  43.  
  44. /***********************************|****************************************/
  45.  
  46. ImplementList(ABuffer,TBufferList,true);
  47. ImplementList(TSession,TSessionList,true);
  48.  
  49. /***********************************|****************************************/
  50.  
  51. #pragma segment Main
  52.  
  53. /***********************************|****************************************/
  54.  
  55. Boolean GetStandardStatusItem ( const ATupleKey& key, ADataItem& item );
  56.  
  57. /***********************************|****************************************/
  58.  
  59. void DoUpdateMonitor (unsigned long g, unsigned long)
  60. {
  61.     TSetRefCon ('MONI');
  62.     if ( g )
  63.         ((TStatusMonitor*) g)->UpdateMonitor();
  64. }
  65.  
  66. /***********************************|****************************************/
  67.  
  68. #pragma segment StatusMonitor
  69.  
  70. /***********************************|****************************************/
  71.  
  72. TStatusMonitor::TStatusMonitor(TMailGateway* gateway):
  73.     TDirectObject (),
  74.     fMonitorThread ( nil ),
  75.     fSessionList (),
  76.     fMailGateway ( gateway )
  77. {
  78. }
  79.  
  80. /***********************************|****************************************/
  81.  
  82. TStatusMonitor::~TStatusMonitor()
  83. {
  84. }
  85.  
  86. /***********************************|****************************************/
  87.  
  88. void TStatusMonitor::UpdateLog(long infoID, char* theMsg)
  89. {
  90.     unsigned long numSessions = fSessionList.Count ();
  91.  
  92.     for ( unsigned long i = 1; i <= numSessions; i++ )
  93.     {
  94.         TSession* theSession = fSessionList.Get(i);
  95.         long sessionID = theSession->GetSessionID();
  96.         unsigned long items = theSession->CountItems();
  97.  
  98.         for (unsigned long index = 1; index <= items; index++)
  99.         {
  100.             long id = theSession->GetItemValue(index);
  101.  
  102.             if ( id == infoID )
  103.             {
  104.                 TAppleEvent theMessage ('stmn','updt',theSession->GetAddress(),kAENoReply);
  105.                 theMessage.WriteLong('SSID',theSession->GetSessionID());
  106.                 theMessage.WriteParameter(id, typeWildCard,theMsg,strlen(theMsg));
  107.                 OSErr temp = noErr;
  108.                 theMessage.Send(temp);
  109.                 break;
  110.             }
  111.         }
  112.     }
  113. }
  114.  
  115. /***********************************|****************************************/
  116.  
  117. OSErr TStatusMonitor::Run()
  118. {
  119.     fMonitorThread = createThread ('MONI', (FNULUL) DoUpdateMonitor, 24000, (unsigned long) this, 0, TNormalMode);
  120.     return noErr;
  121. }
  122.  
  123. /***********************************|****************************************/
  124.  
  125. TSession* TStatusMonitor::FindMatchingSession(const TAddressDescription& theAddress, long docSessionID) const
  126. {
  127.     if ( theAddress.fData.dataHandle )
  128.     {
  129.         long ppcIDA = (*((TargetIDHdl) (theAddress.fData.dataHandle)))->sessionID;
  130.         unsigned long count = fSessionList.Count();
  131.         
  132.         for ( unsigned long i = 1; i <= count; i++)
  133.         {
  134.             TSession* theSession = fSessionList.Get(i);
  135.             TAddressDescription sessionAddress = theSession->GetAddress ();
  136.  
  137.             long ppcIDB = (*((TargetIDHdl) (sessionAddress.fData.dataHandle)))->sessionID;
  138.             
  139.             if ((docSessionID == theSession->GetSessionID()) && (ppcIDA == ppcIDB))
  140.                 return theSession;
  141.         }
  142.     }
  143.     else
  144.         steve << "Why is the FindMatchingSession theAddress.fData.dataHandle nil ? " << endl;
  145.  
  146.     return nil;
  147. }
  148.  
  149. /***********************************|****************************************/
  150.  
  151. void TStatusMonitor::HandleAppleEvents ( const AppleEvent& message, const AppleEvent& reply, long info )
  152. {
  153.     TAppleEvent theMessage ( message );
  154.     // TAddressDescription theAddress;
  155.     long sessionID;
  156.     TSession* theSession;
  157.  
  158.     AEAddressDesc address;
  159.     theMessage.GetAddress(address);
  160.  
  161.     TAddressDescription theAddress ( address );
  162.     theMessage.ReadLong('SSID', sessionID);
  163.  
  164.     switch (info)
  165.     {
  166.          case cStatusLogInit:
  167.          {
  168.             TAppleEvent theReply (reply);
  169.  
  170.             steveF ( 3, "Got cStatusLogInit at " << time << " Session ID " << sessionID );
  171.  
  172.             fSessionList.Delete ( FindMatchingSession ( theAddress,sessionID) );
  173.             TSession* newSession = new TSession(theAddress,sessionID);
  174.             fSessionList.Append(newSession);
  175.  
  176.             theReply.WriteLong('SUPT',cSupportMonitoring);
  177.             OSErr err = noErr;
  178.             theReply.Send(err);
  179.         }
  180.         break;
  181.  
  182.         case cItemsToBeMonitored:
  183.         {
  184.             steveF ( 3, "Got cItemsToBeMonitored at " << time << " Session ID " << sessionID );
  185.  
  186.             TBufferList* list = new TBufferList;
  187.             theMessage.ReadList('INFO', typeLongInteger, *list);
  188.             theSession = FindMatchingSession ( theAddress,sessionID);
  189.  
  190.             #if debug
  191.             if (steveFlag.Flag(3)) {
  192.                 for (unsigned long l = 1; l <= list->Count(); ++l) {
  193.                     ABuffer* buffer = list->Get(l);
  194.                     if (buffer)
  195.                         OutputOSType (steve, * (OSType*) buffer->GetPhysicalStart());
  196.                     steve << " ";
  197.                 }
  198.             }
  199.             #endif
  200.             
  201.             if ( theSession )
  202.                 theSession->SetItemValue ( list );
  203.             else
  204.                 delete list;
  205.             
  206.             fMonitorThread->Wake ();
  207.         }
  208.         break;
  209.  
  210.         case cStopMonitoring:
  211.         {
  212.             steveF ( 3, "Got cStopMonitoring at " << time << " Session ID " << sessionID );
  213.  
  214.             fSessionList.Delete ( FindMatchingSession ( theAddress,sessionID) );
  215.         }
  216.         break;
  217.  
  218.         case cStatusSessionAlive:
  219.         {
  220.             steveF ( 3, "Got cStatusSessionAlive at " << time << " Session ID " << sessionID );
  221.  
  222.             theSession = FindMatchingSession ( theAddress,sessionID);
  223.  
  224.             if (theSession != nil)
  225.                 theSession->ResetTimer();
  226.         }
  227.         break;
  228.  
  229.          case cGetConfigCommand:
  230.          {
  231.             TAppleEvent theReply (reply);
  232.             char s[64];
  233.             
  234.             /* What to do here is */
  235.             /*        1. Call theMessage.ReadXXXX('WFIG', sometype, somePtr)
  236.                         to determine which configuration string is needed
  237.                     2. Retrieve the configuration parameter from where ever
  238.                         if you don't have it return a null string
  239.                     3. Call theReply.WriteParameter ( 'FIGV', sometype, somePtr,length of somePtr); 
  240.                     4. Call theReply.Send(err);
  241.             */
  242.  
  243.             #if 1
  244.             Str255 itemName;
  245.             
  246.             theMessage.ReadParameter ( 'WFIG', itemName );
  247.             
  248.             if ( itemName[0] )
  249.             {    CTupleKey configItem ( itemName );
  250.                 CDataItem value;
  251.             
  252.                 steveF ( 3, "TStatusMonitor::Get Config Item '" << itemName << "'" );
  253.             
  254.                 fMailGateway->GetConfigItem ( configItem, value );
  255.                 
  256.                 theReply.WriteParameter ( 'FIGV', value.GetDataType(), value.GetPhysicalStart(), value.GetPhysicalLength() );
  257.             }
  258.  
  259.             OSErr err = noErr;
  260.             theReply.Send ( err );
  261.             
  262.             #else
  263.  
  264.             /* This code is just here to make it work*/
  265.             strcpy(s,"Hello");
  266.  
  267.             theReply.WriteParameter ( 'FIGV', 'TEXT', s,strlen(s));
  268.             OSErr err = noErr;
  269.             theReply.Send(err);
  270.             
  271.             #endif
  272.  
  273.         }
  274.         break;
  275.                 
  276.         case cSetConfigCommand:
  277.          {
  278.             TAppleEvent theReply (reply);
  279.             char s[64];
  280.             
  281.             /* What to do here is */
  282.             /*        1. Call theMessage.ReadXXXX('WFIG', sometype, somePtr)
  283.                         to determine which configuration string is to be set
  284.                     2. Call theMessage.ReadXXXX('FIGV', sometype, somePtr)
  285.                         to get the value for the configuration parameter
  286.                     3. Validate the Parameter - 
  287.                         If it is OK then 
  288.                             somePtr points to a NULL string
  289.                         If not then somePtr point to an error message string    
  290.                     4. Call theReply.WriteParameter ( 'FIGR', sometype, somePtr,length of somePtr); 
  291.                     5. Call theReply.Send(err);
  292.             */
  293.  
  294.             #if 1
  295.             Boolean ok = false;
  296.             
  297.             Str255 itemName;
  298.             if ( theMessage.ReadParameter ( 'WFIG', itemName ) == noErr )
  299.             {    CTupleKey key ( itemName );
  300.                 CDataItem value;
  301.             
  302.                 if ( theMessage.ReadParameter ( 'FIGV', value ) == noErr )
  303.                 {
  304.                     steveF ( 3, "TStatusMonitor::Set config item '" << itemName << "' to " << value );
  305.  
  306.                     if ( fMailGateway->SetConfigItem ( key, value ) )
  307.                         ok = true;
  308.                 }
  309.             }
  310.             
  311.             if ( ! ok )
  312.             {    CStr255 replyText;
  313.             
  314.                 replyText = "\pThe attempt to set this parameter failed.";
  315.                 
  316.                 theReply.WriteParameter ( 'FIGR', 'TEXT', & replyText[1], replyText[0] );
  317.             }
  318.  
  319.             OSErr err = noErr;
  320.             theReply.Send ( err );
  321.  
  322.             #else
  323.             
  324.             /* This code is just here to make it work*/
  325.             strcpy(s,"");
  326.  
  327.             theReply.WriteParameter ( 'FIGR', 'TEXT', s,strlen(s));
  328.             OSErr err = noErr;
  329.             theReply.Send(err);
  330.             
  331.             #endif
  332.  
  333.         }
  334.         break;
  335.         
  336.         case cMonitorCommand:
  337.         {
  338.             steveF ( 3, "Got cMonitorCommand at " << time << " Session ID " << sessionID );
  339.  
  340.             theSession = FindMatchingSession ( theAddress,sessionID);
  341.             
  342.             /* What to do here is */
  343.             /*        1. Call theMessage.ReadLong('MCMD', somePtr)
  344.                         to determine which command
  345.                         somePtr is a OSType
  346.                     2. Do whatever the command make you do
  347.                     3  If you want the button to have a new title
  348.                         then set the text for that status item and force and update now
  349.                         by calling UpdateMonitor
  350.                     4. No reply is needed    
  351.                 
  352.             */
  353.             
  354.             CDataItem event;
  355.             
  356.             if ( theMessage.ReadParameter ( 'MCMD', event ) == noErr )
  357.             {
  358.                 if ( ! fMailGateway->HandleMonitoringEvent ( event ) )
  359.                 {
  360.                     steveF ( 3, "TStatusMonitor::Event " << event << " unhandled by fMGwy->HandleMonitoringEvent()" );
  361.                 }
  362.             }
  363.         }
  364.         break;
  365.         
  366.         default:
  367.             steveF ( 3, "AppleEvent not handled by StatusMonitor HandleAppleEvents!! " << info );
  368.  
  369.             break;
  370.     }
  371. }
  372.  
  373. /***********************************|****************************************/
  374. /***********************************|****************************************/
  375.  
  376. TSession::TSession ( const TAddressDescription& theAddress, long theSessionID ):
  377.     THandleObject (),
  378.     fAddress ( theAddress ),
  379.     fSessionID ( theSessionID ),
  380.     fMonitorList ( nil )
  381. {
  382.     ResetTimer();
  383. }
  384.  
  385. /***********************************|****************************************/
  386.  
  387. TSession::~TSession()
  388. {
  389.     delete fMonitorList;
  390. }
  391.  
  392. /***********************************|****************************************/
  393.  
  394. void TSession::SetItemValue ( TBufferList* list ) 
  395. {
  396.     delete fMonitorList;
  397.     fMonitorList = list;
  398. }
  399.  
  400. /***********************************|****************************************/
  401.  
  402. Boolean TSession::HasTimerExpired() const
  403. {
  404.     unsigned long secs;
  405.     GetDateTime(&secs);
  406.     return secs - fPeriodicCheckSessionAlive > 10 * 60;
  407. }
  408.  
  409. /***********************************|****************************************/
  410.  
  411. void TSession::ResetTimer()
  412. {
  413.     unsigned long secs;
  414.     GetDateTime(&secs);
  415.     fPeriodicCheckSessionAlive = secs;
  416. }
  417.  
  418. /***********************************|****************************************/
  419.  
  420. long TSession::GetItemValue ( unsigned long index ) const
  421. {
  422.     long theID = 0;
  423.  
  424.     if ( fMonitorList )
  425.     {
  426.         const ABuffer* buffer = fMonitorList->Get ( index );
  427.         
  428.         if ( buffer )
  429.             theID = *(long*) buffer->GetPhysicalStart ();
  430.     }
  431.  
  432.     return theID;
  433. }
  434.  
  435. /***********************************|****************************************/
  436.  
  437. /***********************************|****************************************/
  438.  
  439. Boolean GetStandardStatusItem ( const ATupleKey& key, ADataItem& item )
  440. {    Boolean result = false;
  441.  
  442.     if ( key.GetLength () == sizeof(OSType) )
  443.     {
  444.         switch ( * (OSType *) key.GetData() )
  445.         {
  446.             case 'TIME':    //    Current time (for gateway)
  447.                 item = NowDateTime();
  448.                 result = true;
  449.                 break;            
  450.  
  451.             case 'FMEM':    //    Free memory
  452.                 item = FreeMem();
  453.                 result = true;
  454.                 break;
  455.                 
  456.             case 'DSPC':    //    Disk Free space
  457.             {    
  458.                 Str31 volName;
  459.                 short vRefNum;
  460.                 long freeBytes;
  461.                 
  462.                 if ( GetVInfo ( -1, (StringPtr) &volName, &vRefNum, &freeBytes) == noErr )
  463.                     item = freeBytes;
  464.                 result = true;
  465.                 break;
  466.             }
  467.         }
  468.     }
  469.     
  470.     return result;
  471. }
  472.  
  473.  
  474. /***********************************|****************************************/
  475.  
  476. void TStatusMonitor::UpdateMonitor()
  477. {
  478.     OSErr err;
  479.  
  480.     while ( true )
  481.     {
  482.         // Update the up time flag
  483.  
  484.         unsigned long index = fSessionList.Count ();
  485.         
  486.         while ( index > 0 )
  487.         {
  488.             TSession* theSession = fSessionList.Get ( index );
  489.             long sessionID = theSession->GetSessionID ();
  490.  
  491.             if ( theSession->HasTimerExpired () )
  492.             {
  493.                 steveF ( 3,  "Session Timed out -- killing it at " << time << " SessionID " << sessionID );
  494.  
  495.                 fSessionList.Delete ( theSession );
  496.             }
  497.             else
  498.             {
  499.                 steveF( 3, "Updating session #" << sessionID << " at " << time );
  500.                 
  501.                 TAppleEvent theMessage ('stmn','updt',theSession->GetAddress(),kAENoReply);
  502.                 theMessage.WriteLong('SSID',theSession->GetSessionID());
  503.                 unsigned long items = theSession->CountItems();
  504.  
  505.                 for ( unsigned long jndex = 1; jndex <= items; jndex++ )
  506.                 {
  507.                     long id = theSession->GetItemValue ( jndex );
  508.  
  509.                     CFourByteKey key ( id );
  510.                     CDataItem data;
  511.  
  512.                     Boolean result = GetStandardStatusItem ( key, data );
  513.                     
  514.                     if ( !result )
  515.                         result = fMailGateway->GetStatusItem ( key, data );
  516.                     
  517.                     if ( result )
  518.                     {
  519.                         err = theMessage.WriteParameter ( id, data.GetDataType(), data.GetPhysicalStart (), data.GetPhysicalLength () );
  520.                         if (steveFlag.Flag(3)) {
  521.                             OutputOSType( steve, id); steve << " ";
  522.                             OutputOSType( steve, data.GetDataType() );
  523.                             steve << " (" << data.GetPhysicalLength () << ") ";
  524.                         }
  525.                     }
  526.                 }
  527.                 
  528.                 steveF ( 3, "." );
  529.  
  530.                 theMessage.Send(err);
  531.             }
  532.             
  533.             index--;
  534.         }
  535.         
  536.         #if debug
  537.         TSleep ( steveFlag.Flag ( 4 ) ? 300 : 1800 );
  538.         #else
  539.  
  540.         TSleep ( 60 * 30 );
  541.         
  542.         #endif
  543.     }
  544. }
  545.  
  546. /***********************************|****************************************/
  547.